import java.util.*;
class ConfPoint
{
	long _spin;
	float _temperature;
	long _time;
	float _magneticField;
	ConfPoint(long spin,float temperature,float magneticfield,long time)
	{
		_spin=spin;
		_temperature=temperature;
		_time=time;
		_magneticField=magneticfield;
	}
}
class Lattice
{
	
	private byte _array[][];
	private int _length;
	private int _width;
	void fillWithOnes(boolean plus)
	{
		for(int x=0;x<_length;x++)
			for(int y=0;y<_width;y++)
				if(plus) _array[x][y]=1;
				else _array[x][y]=-1;
	}
	void fillAtRandom()
	{
		for(int x=0;x<_length;x++)
			for(int y=0;y<_width;y++)
				if(Math.random()>0.5) _array[x][y]=1;
				else _array[x][y]=-1;
	}
	long getSpin()
	{
		long spin=0;
		for(int x=0;x<_length;x++)
			for(int y=0;y<_width;y++)
				spin+=_array[x][y];
		return spin;
	}
	byte[][] getArray()
	{
		return _array;
	}
	Lattice(int length,int width)
	{
		_array=new byte[length][width];
		_length=length;
		_width=width;
		fillWithOnes(true);
	}
	int getLength()
	{
		return _length;
	}
	int getWidth()
	{
		return _width;
	}
	int getSize()
	{
		return _length*_width;
	}
	float getEnergy(float magneticField)
	{
		float energy=0;
		for(int x=0;x<_length;x++)
			for(int y=0;y<_width;y++)
				energy+=getOneSpinEnergy(x,y,magneticField);
		return energy;
	}
	float getOneSpinEnergy(int x,int y,float magneticField)
	{
		float energy=0;
		for(int i=x-1;i<=x+1;i++)
		{
			for(int j=y-1;j<=y+1;j++)
			{
				if(i==x&&j==y||i<0||j<0||i>=_length||j>=_width) continue;
				if(_array[x][y]==_array[i][j]) energy+=1.0;
				else energy-=1.0;
			}
			energy+=_array[x][y]*magneticField;
		}
		return energy;
	}
}
class Demon
{
	
	protected Lattice _lattice;
	protected boolean _finished;
	Demon(Lattice lattice)
	{
		_lattice=lattice;
		_finished=true;
	}
	void interact(float temperature,float magneticfield){}
	void setLattice(Lattice lattice)
	{
		_lattice=lattice;
	}
	boolean isFinished()
	{
		return _finished;
	}
	Lattice getLattice()
	{
		return _lattice;
	}
}
class Engine
{
	
	protected LinkedList<Demon> _demons;
	private long _time;
	private float _temperature;
	private float _magneticField;
	private boolean _asymptotic;
	private boolean _freeze;
	private Lattice _lattice;
	Engine(Lattice lattice)
	{
		_lattice=lattice;
		_time=0;
		_temperature=10;
		_magneticField=100;
		_asymptotic=true;
		_freeze=false;
		_demons=new LinkedList<Demon>();
	}
	void step()
	{
		boolean finished=false;
		if(_freeze) _lattice.fillWithOnes(true);
		do
		{
			finished=true;
			updateDemons();
			ListIterator<Demon> dit=_demons.listIterator();
			while(dit.hasNext())
			{
				Demon demon=dit.next();
				demon.interact(_temperature,_magneticField);
				if(!demon.isFinished()) finished=false;
			}
			if(!_asymptotic) break;
		} while (!finished);
	}
	void updateDemons(){}
	void setTemperature(float temperature)
	{
		_temperature=temperature;
	}
	void setMagneticField(float magneticfield)
	{
		_magneticField=magneticfield;
	}
	void setProperties(float temperature,float magneticfield)
	{
		_temperature=temperature;
		_magneticField=magneticfield;
	}
	void clearTime()
	{
		_time=0;
	}
	ConfPoint getPoint()
	{
		return new ConfPoint(_lattice.getSpin(),_temperature,_magneticField,_time);
	}
	float getTemperature()
	{
		return _temperature;
	}
	float getMagneticField()
	{
		return _magneticField;
	}
	long getTime()
	{
		return _time;
	}
	long getSpin()
	{
		return _lattice.getSpin();
	}
	void setFreezing(boolean freeze)
	{
		_freeze=freeze;
	}
	void setAsymptotic(boolean asymptotic)
	{
		_asymptotic=asymptotic;
	}
}
